package com.interf.agv;

import java.util.HashMap;
import java.util.Map;

public class AGVHandler {
	//注册的小车列表
	private Map<String, String> agvs = new HashMap();	//任务调度
	//获取任务小车
	private static final long GET_AGVS = 0x00010001;
	//任务ID
	private static long request_seqid = 51599l;
	//seqid 下标
	private static final int SEQID_INDEX = 4;
	//cmd 下标
	private static final int CMD_INDEX = 8;
	//len 下标
	private static final int LEN_INDEX = 12;
	//cc 下标
	private static final int CC_INDEX = 16;
	//ext 下标
	private static final int EXT_INDEX = 20;

	/**
	 * Long转unit32 byte[]
	 *
	 * @param value
	 * @return
	 */
	public static byte[] LongToBytesLittle2(Long value) {
		byte[] src = new byte[4];
		src[3] = (byte) ((value >> 24) & 0xFF);
		src[2] = (byte) ((value >> 16) & 0xFF);
		src[1] = (byte) ((value >> 8) & 0xFF);
		src[0] = (byte) (value & 0xFF);
		return src;
	}

	/**
	 * 字符串转换成为16进制(无需Unicode编码)
	 *
	 * @param str
	 * @return
	 */
	public static String str2HexStr(String str) {
		char[] chars = "0123456789ABCDEF".toCharArray();
		StringBuilder sb = new StringBuilder("");
		byte[] bs = str.getBytes();
		int bit;
		for (int i = 0; i < bs.length; i++) {
			bit = (bs[i] & 0x0f0) >> 4;
			sb.append(chars[bit]);
			bit = bs[i] & 0x0f;
			sb.append(chars[bit]);
			// sb.append(' ');
		}
		return sb.toString().trim();
	}

	private static String hexStr2Str(String hexStr) {
		String str = "0123456789ABCDEF";
		char[] hexs = hexStr.toCharArray();
		byte[] bytes = new byte[hexStr.length() / 2];
		int n;
		for (int i = 0; i < bytes.length; i++) {
			n = str.indexOf(hexs[2 * i]) * 16;
			n += str.indexOf(hexs[2 * i + 1]);
			bytes[i] = (byte) (n & 0xff);
		}
		return new String(bytes);
	}

	/**
	 * hex字符串转byte数组
	 *
	 * @param inHex 待转换的Hex字符串
	 * @return 转换后的byte数组结果
	 */
	public static byte[] hexToByteArray(String inHex) {
		int hexlen = inHex.length();
		byte[] result;
		if (hexlen % 2 == 1) {
			//奇数
			hexlen++;
			result = new byte[(hexlen / 2)];
			inHex = "0" + inHex;
		} else {
			//偶数
			result = new byte[(hexlen / 2)];
		}
		int j = 0;
		for (int i = 0; i < hexlen; i += 2) {
			result[j] = hexToByte(inHex.substring(i, i + 2));
			j++;
		}
		return result;
	}
	/**
	 * Hex字符串转byte
	 * @param inHex 待转换的Hex字符串
	 * @return 转换后的byte
	 */
	public static byte hexToByte(String inHex) {
		return (byte) Integer.parseInt(inHex, 16);
	}

	/**
	 * 将byte数组转化为16进制
	 *
	 * @param buffer
	 * @return
	 */
	private static String byte2hex(byte[] buffer) {
		String h = "";
		for (int i = 0; i < buffer.length; i++) {
			String temp = Integer.toHexString(buffer[i] & 0xFF);
			if (temp.length() == 1) {
				temp = "0" + temp;
			}
			h = h + temp;
		}
		return h;
	}

	/**
	 * 转二进制的流
	 *
	 * @param str
	 * @return
	 */
	public static String toBinary(String str) {
		//把字符串转成字符数组
		char[] strChar = str.toCharArray();
		String result = "";
		for (int i = 0; i < strChar.length; i++) {
			//toBinaryString(int i)返回变量的二进制表示的字符串
			//toHexString(int i) 八进制
			//toOctalString(int i) 十六进制
			result += Integer.toBinaryString(strChar[i]) + "";
		}
		return result;
	}

	/**
	 * BYTE：starter（协议起始位，方便抓包调试，没有实际意义，当前恒定为0x66）1
	 * BYTE：version（协议版本号，当前恒定为0x01）1
	 * BYTE：compress（0x00表示包体不压缩，0x01表示包体压缩，当前恒定为0x00）1
	 * BYTE：lrc（包头检验码，用来检验包头是否异常，规则见如下描述）
	 * uint32：request_seqid（如果此次为request cmd，需要带上seqid，进程周期内顺序递增；response的时候需要带回seqid）1
	 * uint32：cmd（包的具体指令，不同的cmd有不同的包体）1
	 * uint32：len（包体长度，不包含包头长度）1
	 * uint32：cc（包体校验码，用来检验包体是否异常，规则见如下描述）1
	 * uint32：ext（扩展字段，当前恒定为0）1
	 */
	protected static byte[] getTaskInfo(long order, String body) {

		byte[] taskStr = new byte[24];

		//taskStr的前3位按协议固定，无须改动
		taskStr[0] = 0x66;
		taskStr[1] = 0x01;
		taskStr[2] = 0x00;

		//每调用一次方法，都将自动增加一次指令的请求次数
		byte[] seqid = LongToBytesLittle2(request_seqid++);
		byte[] cmd = LongToBytesLittle2(order);
		byte[] ext = LongToBytesLittle2(0l);
		//直接头信息处理
		System.arraycopy(seqid, 0, taskStr, SEQID_INDEX, 4);
		System.arraycopy(cmd, 0, taskStr, CMD_INDEX, 4);
		System.arraycopy(ext, 0, taskStr, EXT_INDEX, 4);
		//整合cc检验字段
		long occ = 0l;
		for (byte t : body.getBytes()) {
			occ += t;
		}
		byte[] cc = LongToBytesLittle2(occ);
		System.arraycopy(cc, 0, taskStr, CC_INDEX, 4);
		//整合head中的len
		//body = str2HexStr(body);
		byte[] taskBody = body.getBytes();
		byte[] len = LongToBytesLittle2((long) taskBody.length);
		//命令
		byte[] taskOrder = new byte[24 + taskBody.length];

		System.arraycopy(len, 0, taskStr, LEN_INDEX, 4);
		//整合lrc
		byte lrc = 0;
		for (int i = 0; i < taskStr.length; i++) {
			lrc ^= taskStr[i];
		}
		taskStr[3] = lrc;

		//复制头信息
		System.arraycopy(taskStr, 0, taskOrder, 0, 24);
		//复制主信息
		System.arraycopy(taskBody, 0, taskOrder, 24, taskBody.length);

		return taskOrder;
	}

	/**
	 * 获取头信息
	 *
	 * @param order
	 * @return
	 */
	protected static byte[] getTaskInfo(long order) {
		byte[] taskStr = new byte[24];

		//taskStr的前3位按协议固定，无须改动
		taskStr[0] = 0x66;
		taskStr[1] = 0x01;
		taskStr[2] = 0x00;

		//每调用一次方法，都将自动增加一次指令的请求次数
		byte[] seqid = LongToBytesLittle2(request_seqid++);
		byte[] cmd = LongToBytesLittle2(order);
		byte[] ext = LongToBytesLittle2(0l);
		byte[] len = LongToBytesLittle2(0l);
		//直接头信息处理
		System.arraycopy(seqid, 0, taskStr, SEQID_INDEX, 4);
		System.arraycopy(cmd, 0, taskStr, CMD_INDEX, 4);
		System.arraycopy(ext, 0, taskStr, EXT_INDEX, 4);
		//整合cc检验字段
		long occ = 0l;
		byte[] cc = LongToBytesLittle2(occ);
		System.arraycopy(cc, 0, taskStr, CC_INDEX, 4);
		//整合head中的len
		//body = str2HexStr(body);

		System.arraycopy(len, 0, taskStr, LEN_INDEX, 4);
		//整合lrc
		byte lrc = 0;
		for (int i = 0; i < taskStr.length; i++) {
			lrc ^= taskStr[i];
		}
		taskStr[3] = lrc;
		//复制头信息
		//复制主信息
		return taskStr;
	}
}
